package com.eedi.framework.notify.service;

import com.google.common.annotations.VisibleForTesting;
import com.eedi.framework.common.enums.CommonStatusEnum;
import com.eedi.framework.common.exception.util.PreconditionsUtils;
import com.eedi.framework.common.exception.util.ServiceExceptionUtil;
import com.eedi.framework.common.pojo.PageResult;
import com.eedi.framework.common.util.object.BeanUtils;
import com.eedi.framework.notify.controller.sys.vo.SysNoticePageReq;
import com.eedi.framework.notify.controller.sys.vo.SysNoticeResp;
import com.eedi.framework.notify.controller.sys.vo.SysNoticeSaveReq;
import com.eedi.framework.notify.controller.sys.vo.SysNoticeUpReq;
import com.eedi.framework.notify.dal.dataobject.SysNoticeDO;
import com.eedi.framework.notify.enums.SysNoticeErrorCodeConstants;
import com.eedi.framework.notify.dal.mapper.NoticeMapper;
import com.eedi.sys.facade.SysUserFacade;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;

import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static com.eedi.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.eedi.framework.notify.enums.SysNoticeErrorCodeConstants.SYS_NOTICE_NOT_STATUS_IS_DISABLE;
import static com.eedi.framework.notify.enums.SysNoticeErrorCodeConstants.SYS_NOTICE_NOT_STATUS_IS_ENABLE;

/**
 * 通知公告 Service 实现类
 *
 * @author 永聚长青源码
 */
@Service
@Validated
public class SysNoticeServiceImpl implements SysNoticeService {

    @Resource
    private NoticeMapper noticeMapper;
    @Resource
    private SysUserFacade sysUserFacade;

    @Override
    public String createNotice(SysNoticeSaveReq createReqVO) {
        SysNoticeDO notice = BeanUtils.toBean(createReqVO, SysNoticeDO.class);
        noticeMapper.insert(notice);
        return notice.getSysNoticeId();
    }

    @Override
    public void updateNotice(SysNoticeUpReq updateReqVO) {
        // 校验是否存在
        validateNoticeExists(updateReqVO.getSysNoticeId());
        // 更新通知公告
        SysNoticeDO updateObj = BeanUtils.toBean(updateReqVO, SysNoticeDO.class);
        noticeMapper.updateById(updateObj);
    }

    @Override
    public void enable(String sysNoticeId) {
        SysNoticeResp notice = getNotice(sysNoticeId);
        PreconditionsUtils.checkArgument(
                !Objects.equals(CommonStatusEnum.ENABLE.getCode(), notice.getSysNoticeStatus().getCode()),SYS_NOTICE_NOT_STATUS_IS_ENABLE
        );
        noticeMapper.updateStatusById(sysNoticeId,CommonStatusEnum.ENABLE);
    }

    @Override
    public void disable(String sysNoticeId) {
        SysNoticeResp notice = getNotice(sysNoticeId);
        PreconditionsUtils.checkArgument(
               ! Objects.equals(CommonStatusEnum.DISABLE.getCode(), notice.getSysNoticeStatus().getCode()),SYS_NOTICE_NOT_STATUS_IS_DISABLE
        );
        noticeMapper.updateStatusById(sysNoticeId,CommonStatusEnum.DISABLE);
    }

    @Override
    public void deleteNotice(String id) {
        // 校验是否存在
        validateNoticeExists(id);
        // 删除通知公告
        noticeMapper.deleteById(id);
    }

    @Override
    public PageResult<SysNoticeResp> getNoticePage(SysNoticePageReq reqVO) {
        PageResult<SysNoticeResp> sysNoticeRespPageResult = noticeMapper.selectPage(reqVO);
        sysUserFacade.fillInUserName(sysNoticeRespPageResult.getList(),SysNoticeResp::getCreator,SysNoticeResp::setCreatorName);
        return sysNoticeRespPageResult;
    }

    @Override
    public SysNoticeResp getNotice(String id) {
        SysNoticeDO sysNoticeDO = noticeMapper.selectById(id);
        SysNoticeResp bean = BeanUtils.toBean(sysNoticeDO, SysNoticeResp.class);
        sysUserFacade.fillInUserName(bean.getCreator(),bean::setCreatorName);
        return bean;
    }

    @Override
    public List<SysNoticeResp> getNoticeNotInIds(Collection<String> sysNoticeIds) {
        return noticeMapper.selectNotInIds(sysNoticeIds);
    }


    @VisibleForTesting
    public void validateNoticeExists(String id) {
        if (id == null) {
            return;
        }
        SysNoticeDO notice = noticeMapper.selectById(id);
        if (notice == null) {
            throw ServiceExceptionUtil.exception(SysNoticeErrorCodeConstants.SYS_NOTICE_NOT_FOUND);
        }
    }

}
